package com.coocaa.app.lib.cleaner.deleter.pkgdata.impl;

import android.content.Context;
import android.content.pm.IPackageDataObserver;
import android.content.pm.PackageManager;
import android.os.RemoteException;

import com.coocaa.app.lib.cleaner.deleter.pkgdata.PackageDataDeleterFactory;
import com.coocaa.app.lib.cleaner.mgr.DataHolder;
import com.coocaa.app.lib.cleaner.u.AsyncReturn;

import java.io.File;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;

/**
 * Created by lu on 17-4-18.
 */

public class PackageDataDeleterImpl2 implements PackageDataDeleterFactory.PackageDataDeleter {

    private static long deleteApplicationUserData(PackageManager pm, final DataHolder.SinglePackageData data, final PackageDataDeleterListener listener) throws Exception {
        final AsyncReturn<Long> ret = new AsyncReturn<Long>(Long.valueOf(0));
        final CountDownLatch latch = new CountDownLatch(1);
        Method deleteApplication = pm.getClass().getMethod(
                "clearApplicationUserData", String.class,
                IPackageDataObserver.class);
        deleteApplication.invoke(pm, data.packageName,
                new IPackageDataObserver.Stub() {
                    @Override
                    public void onRemoveCompleted(String packageName,
                                                  boolean succeeded) throws RemoteException {
                        if (succeeded)
                            ret.set(data.size);
                        latch.countDown();
                    }
                });
        latch.await();
        return ret.get();
    }

    private static long deleteFile(File file) {
        long size = 0;
        if (file != null && file.exists()) {
            if (file.isDirectory()) {
                File[] files = file.listFiles();
                if (files != null) {
                    for (File f : files)
                        size += deleteFile(f);
                }
                file.delete();
            } else {
                size = file.length();
                file.delete();
            }
        }
        return size;
    }

    private static long deleteApplicationFiles(DataHolder.SinglePackageData data, final PackageDataDeleterListener listener) {
        if (listener != null)
            listener.onPackageDataDeleterStart(data.packageName);
        long size = 0;
        for (String file : data.files) {
            File _file = new File(file);
            size += deleteFile(_file);
        }
        return size;
    }

    private synchronized void start(final PackageManager pm, final List<DataHolder.SinglePackageData> datas, final PackageDataDeleterListener listener) {
        DeleterThread.post(new Runnable() {

            private void deleteOne(DataHolder.SinglePackageData data) {
                try {
                    if (listener != null)
                        listener.onPackageDataDeleterStart(data.packageName);
                    long size;
                    if (data.files == null || data.files.size() == 0) {
                        size = deleteApplicationUserData(pm, data, listener);
                    } else {
                        size = deleteApplicationFiles(data, listener);
                    }
                    if (listener != null)
                        listener.onPackageDataDeleterEnd(data.packageName, true, size);
                } catch (Exception e) {
                    e.printStackTrace();
                    if (listener != null) {
                        listener.onPackageDataDeleterEnd(data.packageName, false, 0);
                    }
                }
                if (holder != null)
                    holder.removePackageData(data);
            }

            @Override
            public void run() {
                List<DataHolder.SinglePackageData> _datas = new ArrayList<DataHolder.SinglePackageData>(datas);
                if (listener != null)
                    listener.onPackageDataDeleterAllStart();
                for (DataHolder.SinglePackageData data : _datas)
                    deleteOne(data);
                if (listener != null)
                    listener.onPackageDataDeleterAllEnd();
            }
        });
    }

    private DataHolder holder;

    @Override
    public void init(DataHolder holder) {
        this.holder = holder;
    }

    @Override
    public void delete(Context context, DataHolder.SinglePackageData data, PackageDataDeleterListener listener) {
        List<DataHolder.SinglePackageData> datas = new ArrayList<DataHolder.SinglePackageData>();
        datas.add(data);
        start(context.getPackageManager(), datas, listener);
    }

    @Override
    public void delete(Context context, List<DataHolder.SinglePackageData> datas, PackageDataDeleterListener listener) {
        start(context.getPackageManager(), datas, listener);
    }
}
